package org.example.employ_api.service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.example.employ_api.dto.ExperienceSearchDto;
import org.example.employ_api.dto.GraduateInfoDto;
import org.example.employ_api.model.GraduateInfo;
import org.example.employ_api.repository.GraduateInfoRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import jakarta.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class ExperienceService {

    private final GraduateInfoRepository graduateInfoRepository;

    public Page<GraduateInfoDto> searchExperiences(ExperienceSearchDto searchDto) {
        Pageable pageable = PageRequest.of(searchDto.getPage(), searchDto.getSize());

        Specification<GraduateInfo> spec = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();

            if (searchDto.getMajor() != null && !searchDto.getMajor().trim().isEmpty()) {
                predicates.add(cb.equal(root.get("major"), searchDto.getMajor().trim()));
            }

            if (searchDto.getCareerPath() != null && !searchDto.getCareerPath().trim().isEmpty()) {
                predicates.add(cb.equal(root.get("careerPath"), searchDto.getCareerPath().trim()));
            }

            if (searchDto.getExperienceType() != null && !searchDto.getExperienceType().trim().isEmpty()) {
                predicates.add(cb.equal(root.get("experienceType"), searchDto.getExperienceType().trim()));
            }

            if (searchDto.getKeyword() != null && !searchDto.getKeyword().trim().isEmpty()) {
                String keyword = "%" + searchDto.getKeyword().trim() + "%";
                predicates.add(cb.or(
                    cb.like(root.get("experience"), keyword),
                    cb.like(root.get("skills"), keyword),
                    cb.like(root.get("workplace"), keyword),
                    cb.like(root.get("position"), keyword)
                ));
            }

            return predicates.isEmpty() ? cb.conjunction() : cb.and(predicates.toArray(new Predicate[0]));
        };

        Page<GraduateInfo> page = graduateInfoRepository.findAll(spec, pageable);
        
        log.debug("Search results count: {}", page.getContent().size());
        log.debug("Search criteria - major: {}, careerPath: {}, experienceType: {}, keyword: {}",
                searchDto.getMajor(), searchDto.getCareerPath(), 
                searchDto.getExperienceType(), searchDto.getKeyword());

        return page.map(this::convertToDto);
    }

    private GraduateInfoDto convertToDto(GraduateInfo graduateInfo) {
        GraduateInfoDto dto = new GraduateInfoDto();
        dto.setId(graduateInfo.getId());
        dto.setName(graduateInfo.getName());
        dto.setMajor(graduateInfo.getMajor());
        dto.setGraduationYear(graduateInfo.getGraduationYear());
        dto.setCareerPath(graduateInfo.getCareerPath());
        dto.setWorkplace(graduateInfo.getWorkplace());
        dto.setPosition(graduateInfo.getPosition());
        dto.setLocation(graduateInfo.getLocation());
        dto.setGpa(graduateInfo.getGpa());
        dto.setAwards(graduateInfo.getAwards());
        dto.setSkills(graduateInfo.getSkills());
        dto.setExperience(graduateInfo.getExperience());
        dto.setExperienceType(graduateInfo.getExperienceType());
        return dto;
    }
} 